package com.thfw.test.utils;

import android.text.TextUtils;
import android.util.Log;

import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 字符串工具类
 * Created by jiangwj on 2014/7/24.
 */
public final class StringUtils {

    /**
     * 判断字符串是否为空
     * @param s 需要判定的字符串
     * @return 字符串为空或null时返回true
     */
    public static boolean isEmpty(String s) {
        return s == null || s.length() == 0 || "null".equals(s);
    }

    /**
     * 判断字符串是否不为空
     * @param s 需要判定的字符串
     * @return 字符串为空或null时返回true
     */
    public static boolean notEmpty(String s) {
        return s != null && s.length() != 0 && !"null".equals(s);
    }

    /**
     * 两字符串是否相等（包含为 null 的判断）
     * （两个字符串都为 null 时也判断为相等）
     *
     * @param s1 字符串1
     * @param s2 字符串2
     * @return 两字符串相同时返回为 true
     */
    public static boolean equals(String s1, String s2) {
        if (s1 == s2) return true;
        return !(s1 == null || s2 == null) && s1.equals(s2);
    }

    /**
     * 数值字符串转成整形
     * @param str           数值字符串
     * @param defaultVal    默认值
     * @return 数值字符串对应的整形值
     */
    public static int toInt(String str, int defaultVal) {
        int val = defaultVal;
        try {
            val = Integer.parseInt(str);
        } catch (Exception e) {
            val = defaultVal;
        }

        return val;
    }

    public static long toLong(String str, long defaultVal) {
        long val = defaultVal;
        try {
            val = Long.parseLong(str);
        } catch (Exception e) {
            val = defaultVal;
        }

        return val;
    }

    public static float toFloat(String str, float defaultVal) {
        float val = defaultVal;
        try {
            val = Float.parseFloat(str);
        } catch (Exception e) {
            val = defaultVal;
        }

        return val;
    }

    public static double toDouble(String str, double defaultVal) {
        double val = defaultVal;
        try {
            val = Double.parseDouble(str);
        } catch (Exception e) {
            val = defaultVal;
        }

        return val;
    }

    /**
     * "1001110101" 这样的字符串 转换成 BitSet
     * @param s 需要转换的字符串
     * @return 当字符串为空时返回 null，当字符串中包含 '1','0' 之外的字符时返回 null。
     */
    public static BitSet bitString2BitSet(String s) {
        if (s == null) return null;
        s = s.trim();
        if (s.length() == 0) return null;
        BitSet bs = new BitSet(s.length());
        char chs[] = s.toCharArray();
        for (int i = 0; i < chs.length; i++) {
            if (chs[i] == '1') {
                bs.set(i, true);
            } else if (chs[i] == '0') {
                bs.set(i, false);
            } else {
                return null;
            }
        }
        return bs;
    }

    /**
     * 将 BitSet 输出为 "100010101110" 这样的字符串
     * @param bs 需要转换的bit串
     * @return 输出为1,0组成的字符串
     */
    public static String bitSet2BitString(BitSet bs) {
        if (bs == null) return "";
        StringBuilder buf = new StringBuilder(bs.size());
        for (int i = 0; i < bs.size(); i++) {
            buf.append(bs.get(i) ? '1' : '0');
        }
        return buf.toString();
    }

    /**
     * 将字节数组转换成 16进制字符串
     * @param data 需要转换的数据
     * @return 返回16禁止字符串
     */
    public static String bytes2Hex(byte[] data) {
        if (data == null || data.length == 0) return "";
        StringBuilder sb = new StringBuilder();
        for (byte b : data) {
            sb.append(byte2Hex(b));
        }
        //
        return sb.toString();
    }

    /**
     * 将字节转换成16进制字符串
     * @param b 需要转换的数据
     * @return 返回16禁止字符串
     */
    public static String byte2Hex(byte b) {
        char[] chs = new char[2];
        chs[0] = HEX[(b >>> 4) & 0xF];
        chs[1] = HEX[b & 0xF];
        return new String(chs);
    }

    // 用于匹配手机号码
    private final static String REGEX_MOBILE_PHONE = "^0?1[34578]\\d{9}$";

    private static Pattern PATTERN_MOBILE_PHONE = Pattern.compile(REGEX_MOBILE_PHONE);

    /**
     * 判断是否为手机号码
     *
     * @param number
     *            手机号码
     * @return
     */
    public static boolean isCellPhone(String number) {
        Matcher match = PATTERN_MOBILE_PHONE.matcher(number);
        return match.matches();
    }

    private static final char[] HEX = {
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
    };


    /**
     * 获取字符串首字母（如果是中文，则返回汉语拼音的首字母）
     * @param s 字符串
     * @return 字符串的首字母
     */
    public static char getFirstLetter(String s) {
        if (isEmpty(s)) return 0;
        return getFirstLetter(s.charAt(0));
    }

    /**
     * 如果是中文，返回每个字的拼音首字母组成的字符串
     * @param s 字符串
     * @return 每个单词首字母组成的字符串
     */
    public static String getFirstLetterString(String s) {
        if (isEmpty(s)) return "";
        StringBuilder buf = new StringBuilder(s.length());
        for (char c : s.toCharArray()) {
            buf.append(getFirstLetter(c));
        }
        return buf.toString();
    }

    /**
     * 返回拼音首字母
     * @param c 中文字
     * @return 首字母
     */
    public static char getFirstLetter(char c) {
        byte[] chCode = null;
        try {
            chCode = String.valueOf(c).getBytes("GBK");
        } catch (UnsupportedEncodingException ex) {
            // Ignore.
        }
        // 非汉字
        if ((chCode[0] & 0xFF) < 128 && (chCode[0] & 0xFF) > 0) {
            return c;
        }
        return getPinYinFirstLetter(chCode);
    }

    //
    private static char getPinYinFirstLetter(byte[] chCode) {
        char result = '-';
        int secPosValue = 0;
        for (int i = 0; i < chCode.length; i++) {
            chCode[i] -= GB_SP_DIFF;
        }
        secPosValue = chCode[0] * 100 + chCode[1];
        for (int i = 0; i < 23; i++) {
            if (secPosValue >= secPosValueList[i] && secPosValue < secPosValueList[i + 1]) {
                result = firstLetter[i];
                break;
            }
        }
        return result;
    }
    static final int GB_SP_DIFF = 160;
    // 存放国标一级汉字不同读音的起始区位码
    static final int[] secPosValueList = { 1601, 1637, 1833, 2078, 2274, 2302, 2433, 2594, 2787, 3106, 3212, 3472, 3635, 3722, 3730, 3858, 4027, 4086, 4390, 4558, 4684, 4925, 5249, 5600 };
    // 存放国标一级汉字不同读音的起始区位码对应读音
    static final char[] firstLetter = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'w', 'x', 'y', 'z' };


    /**
     * 构建一个URL
     * @param protocol http,https,ftp,ws,...
     * @param host IP或主机名
     * @param port 端口号
     * @param path 路径
     * @param params 参数
     * @return 最终组成的URL对象
     * @throws MalformedURLException
     */
    public static URL buildURL(String protocol, String host, int port, String path, Map<String, String> params) throws MalformedURLException {
        if (port <= 0) port = 80;
        StringBuilder buf = new StringBuilder(protocol);
        buf.append("://").append(host).append(":").append(port).append('/');
        if (notEmpty(path)) {
            buf.append(path);
        }
        if (params != null && params.size() > 0) {
            buf.append('?');
            boolean firstParam = true;
            for (Map.Entry<String, String> ent : params.entrySet()) {
                if (firstParam) firstParam = false;
                else buf.append('&');
                try {
                    buf.append(URLEncoder.encode(ent.getKey(), "UTF-8")).append('=').append(URLEncoder.encode(ent.getValue(), "UTF-8"));
                } catch (UnsupportedEncodingException e) {
                    Log.e("URLEncoder.encode", e.getMessage());
                }
            }
        }
        //
        return new URL(buf.toString());
    }


    /**
     * 移除掉字符串中的 HTML 标签
     * @param s    字符串
     * @return 不含HTML标签的字符串
     */
    public static String trimHtml(final String s) {
        if (s == null) return "";
        StringBuilder buf = new StringBuilder(s.length());
        //  注：如果是 < 的话，在找到下一个 < 或者 字符串结束前，一直查找到 > 为止。移除掉 <> 以及之间的内容
        // 1. 遇到 < 开始找 > ，并添加之前的字符串。
        // 2. 找到 > 忽略之间的字符串。
        // 3. 一直到下一个 < 还没找到 > ，添加之间的字符串。
        // 4. 直到字符串末尾还未找到 > ，添加之间的字符串。
        // 5. 找下一个 < 。
        // 6. 直到字符串末尾未找到 < ，添加之间的字符串。
        final int len = s.length();
        int i0, i1 = 0;
        _find:  while (0 <= (i0 = s.indexOf('<', i1))) {
            buf.append(s.substring(i1, i0));
            for (int i = i0 + 1; i < len; i++) {
                char c = s.charAt(i);
                if (c == '>') {
                    i1 = i + 1;
                    continue _find; // ignore current tag & find next tag
                } else if (c == '<') {
                    buf.append(s.substring(i0, i));
                    i1 = i;
                    continue _find; // append pre-string to next tag & find next
                }
            }
            // not found(current tag end or next tag begin), append to end of string
            i1 = i0;
            break;
        }
        if (i1 <= len) {
            buf.append(s.substring(i1));
        }
        //
        return buf.toString();
    }




    public static String List2String(List<String> list) {
        if (list == null || list.size() == 0) return null;
        StringBuffer sb = new StringBuffer();
        for (String s : list) {
            sb.append(s).append(",");
        }
        return sb.substring(0, sb.length() - 1);
    }

    public static List<String> String2List(String s) {
        if (TextUtils.isEmpty(s)) return null;
        List<String> list = new ArrayList<String>();
        String[] array = s.split("(,)+");
        for (String item : array) {
            if (!TextUtils.isEmpty(item)) {
                list.add(item);
            }
        }
        return list;
    }

    /**
     * byte数组转16进制字符串
     * @param buffer
     * @return
     */
    public static String toHex(byte[] buffer) {
        if (buffer == null) return null;
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buffer.length; i++) {
            sb.append(Character.forDigit((buffer[i] & 0xf0) >> 4, 16));
            sb.append(Character.forDigit(buffer[i] & 0x0f, 16));
        }
        return sb.toString();
    }

    public static String sha(String string) {
        if (TextUtils.isEmpty(string)) {
            return "";
        }
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("sha-256");
            byte[] bytes = md5.digest((string ).getBytes());
            String result = "";
            for (byte b : bytes) {
                String temp = Integer.toHexString(b & 0xff);
                if (temp.length() == 1) {
                    temp = "0" + temp;
                }
                result += temp;
            }
            return result;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }


}
